package com.atwu.wl2022.controller;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.atwu.wl2022.entity.*;
import com.atwu.wl2022.service.*;
import com.atwu.wl2022.util.UUIDUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.websocket.server.PathParam;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * 不需要登录就能访问的页面和功能
 *
 * @author wulejay
 */
@Controller
@Slf4j
public class PageController {

	@Autowired
	IArticleService iArticleService;

	@Autowired
	IUserService iUserService;

	@Autowired
	ITypeService iTypeService;

	@Autowired
	ICommentService iCommentService;

	@Autowired
	IDiaryService iDiaryService;

	@Autowired
	ILinkService iLinkService;


	@GetMapping("/toForget")
	public String toForget() {
		return "user/forget";
	}

	@GetMapping("/toMe")
	public String toMe() {
		return "me";
	}


	/**
	 * 主页面跳转，去登陆页面
	 *
	 * @return 登陆页面
	 */
	@GetMapping("/toLogin")
	public String toLogin() {
		return "user/login";
	}


	/**
	 * 登陆页面跳转，去注册页面
	 *
	 * @return 注册页面
	 */
	@GetMapping("/toRegister")
	public String toRegister() {
		return "user/register";
	}


	/**
	 * 校验邮箱中的code激活账户
	 * 首先根据激活码code查询用户，之后再把状态修改为"1"
	 */
	@GetMapping(value = "/selectCode")
	public String checkCode(@RequestParam("code") String code, Model model) {
		User user = iUserService.checkCode(code);
		log.info("验证的用户信息为：{}", user);
		//如果用户不等于null，把用户状态修改status=1
		if (user != null) {
			user.setStatus(1);
			//把code验证码清空，已经不需要了
			user.setCode("");
			log.info("用户===={}===成功激活", user);
			iUserService.updateUserStatus(user);
			model.addAttribute("msg", "恭喜你，已激活，快登录吧！");
		}else {
			model.addAttribute("msg", "激活失败,试试重新注册！");
		}
		return "user/login";
	}

	/**
	 * 注册
	 *
	 * @param userName 账号
	 * @param password 密码
	 * @param email    邮箱地址
	 * @return 登录页
	 */
	@GetMapping(value = "/registerUser")
	public String register(@PathParam("userName") String userName, @PathParam("password") String password, @PathParam("nickName") String nickName, @PathParam("email") String email, Model model) {
		model.addAttribute("msg2", null);
		String code = UUIDUtils.getUUID() + UUIDUtils.getUUID();
		String image;
		//随机设置用户头像，将头像名存入数据库中
		// 1、生成随机图片名
		Random random = new Random();
		String defaultImage = (random.nextInt(10) + 1) + ".webp";
		log.info("用户的随机头像名为：{}", defaultImage);
		image = defaultImage;
		//2、将数据封装存入数据库
		User user = new User(0, userName, password, email, 0, code, image, nickName, new Date(),0);
		log.info("注册的用户信息为:{}", user);
		boolean register = iUserService.register(user);
		if (register) {
			return "user/login";
		} else {
			model.addAttribute("msg2", "注册失败，该账号已被占用");
			return "user/register";
		}
	}


	/**
	 * 忘记密码
	 *
	 * @return 传给邮箱的验证码
	 */
	@PostMapping("/toForgetPassword")
	@ResponseBody
	public Boolean forgetPassword(String username,String email, HttpSession session) {
		//通过用户名查找用户
		User user = iUserService.getOne(new QueryWrapper<User>().eq("user_name", username).eq("Email",email).select("user_name"));
		log.info("通过username:{},Email:{}.找到的user:{}",username,email, user);
		return user != null;
	}

	/**
	 * 发送验证码功能
	 */
	@PostMapping("/toSendCaptcha")
	@ResponseBody
	public String sendCaptcha(String email, HttpSession session) {
		String captcha = iUserService.sendCaptcha(email);
		log.info("激活码为：{}", captcha);
		return captcha;
	}

	/**
	 * 验证成功，开始修改密码
	 */
	@ResponseBody
	@PostMapping("/resetPassword")
	public Boolean resetPassword(String password,String username) {
		return iUserService.update(new UpdateWrapper<User>().eq("user_name", username).set("password", password));
	}


	/**
	 * 处理登录逻辑
	 * 登陆成功就跳转到index页面，并在右上角显示 用户姓名
	 * 登陆失败就重定向到登陆页面，将错误信息回显
	 *
	 * @param username 用户账号
	 * @param password 用户密码
	 * @return 页面
	 */
	@GetMapping("/login")
	public String login(String username, String password, Model model, HttpSession session) {
		model.addAttribute("msg", null);
		model.addAttribute("msg2", null);
		//创建一个QueryWrapper的对象
		QueryWrapper<User> wrapper = new QueryWrapper<>();
		//通过QueryWrapper设置条件
		//ge gt le lt
		//第一个参数是字段的名称 ， 第二个参数是设置的值
		wrapper.eq("user_name", username);
		User userByName = iUserService.getOne(wrapper);
		wrapper.eq("password", password);
		User one = iUserService.getOne(wrapper);
		log.info("使用账号：{}，密码：{}，在数据库中查出的数据为；{}", username, password, one);
		if (one != null) {
			if(one.getStatus()!=1){
				iUserService.removeById(one.getId());
				model.addAttribute("msg", "注册未成功，账号信息已被清除，请重新注册！");
				return  "user/login";
			}else {
				session.setAttribute("loginUserId", one.getId());
				session.setAttribute("identity", one.getIdentity());
				session.setAttribute("nickName", one.getNickName());
				session.setAttribute("image", one.getImage());
				session.setAttribute("email", one.getEmail());
				session.setAttribute("userName", one.getUserName());

				model.addAttribute("msg", null);
				//根据用户的username找出用户，将访问时间更新
				iUserService.update(new UpdateWrapper<User>().eq("user_name", username).set("date_time", new Date()));
				return "redirect:/article";
			}
		} else {
			model.addAttribute("msg", "您还未注册，请先注册！");
			if (userByName != null) {
				model.addAttribute("msg", "密码错误，您或许可以试试“忘记密码”！");
			}
			return "user/login";
		}
	}


	/**
	 * 进入首页将要从数据库获取最热门的文章信息，即访问量前三名，如果没有，就默认从先到后
	 *
	 * @return 首页
	 */
	@GetMapping({"/index", "/"})
	public String index(HttpSession session) {
		if (session.getAttribute("mostPopularArticles") == null || session.getAttribute("mostPopularArticles") == "") {
			List<Article> mostPopularArticles = iArticleService.getMostPopularArticles();
			if(mostPopularArticles!=null){
				session.setAttribute("mostPopularArticles", mostPopularArticles);
			}else {
				session.setAttribute("mostPopularArticles", "");
			}
		}
		return "index";
	}

	/**
	 * @return 友链页面
	 */
	@GetMapping("/link")
	public String link(Model model) {
		List<Link> linkList = iLinkService.list(new QueryWrapper<Link>().orderByAsc("time"));
		model.addAttribute("linkList", linkList);
		return "link";
	}


	/**
	 * @return 文章列表页 （所有博客）
	 */
	@GetMapping("/article")
	public String article(HttpServletRequest request) {


		//将文章信息封装存进request域中，首先将有置顶状态的文章存入集合，再存入剩余文章
		List<Article> topRecommendation = iArticleService.list(new QueryWrapper<Article>().select("id", "create_date", "create_by", "title", "summary", "image", "article_type", "views","quote_link","is_top", "commentSize").eq("is_top", "1").orderByDesc("create_date").last("limit 3"));

		//获取文章中置顶状态为1的文章，按照创造时间选择最后创造的3个，只封装标题和id和类型
		request.setAttribute("topRecommendation", topRecommendation);

		ArrayList<Article> articleList = new ArrayList<>(topRecommendation);
		List<Article> list2 = iArticleService.list(new QueryWrapper<Article>().select("id", "create_date", "create_by", "title", "summary", "image", "article_type","quote_link", "views", "commentSize").eq("is_top", "0").orderByDesc("create_date"));
		articleList.addAll(list2);
		request.setAttribute("articleList", articleList);

		//将类型信息封装存进request域中
		List<Type> categoryNavigation = iTypeService.list();
		request.setAttribute("categoryNavigation", categoryNavigation);

		//获取点赞数量最多的8个文章进行遍历，只封装标题和id和类型
		List<Article> popularArticles = iArticleService.list(new QueryWrapper<Article>().select("id", "title", "article_type").orderByDesc("likes").last("limit 8"));
		request.setAttribute("popularArticles", popularArticles);

		//12个最新访客，每当用户登录一次，更新他的创建时间，这样就可以判断最新访客，只封装昵称和头像
		List<User> recentVisitors = iUserService.list(new QueryWrapper<User>().select("nick_name", "image").orderByDesc("date_time").last("limit 12"));
		request.setAttribute("recentVisitors", recentVisitors);

		return "article";
	}


	/**
	 * @return article页面异步刷新的数据
	 */
	@PostMapping("/retrieveArticle")
	public String getArticleListByType(String typeId, Model model, HttpServletRequest request) {
		int parseInt = Integer.parseInt(typeId);
		//将类型信息封装存进request域中
		List<Type> categoryNavigation = iTypeService.list();
		request.setAttribute("categoryNavigation", categoryNavigation);
		if (parseInt == 0) {
			//获取全部文章
			// 首先将有置顶状态的文章存入集合
			List<Article> list1 = iArticleService.list(new QueryWrapper<Article>().select("id", "create_date", "create_by", "title", "summary", "image", "article_type", "views","quote_link", "is_top", "commentSize").eq("is_top", "1").orderByDesc("create_date"));
			ArrayList<Article> articleList = new ArrayList<>(list1);

			// 再存入剩余文章
			List<Article> list2 = iArticleService.list(new QueryWrapper<Article>().select("id", "create_date", "create_by", "title", "summary", "image", "article_type", "views", "quote_link","commentSize").eq("is_top", "0").orderByDesc("create_date"));
			articleList.addAll(list2);
			model.addAttribute("articleList", articleList);
			return "article::articleList";

		} else {
			//根据类型查找文章
			// 首先将有置顶状态类型的文章存入集合
			List<Article> list3 = iArticleService.list(new QueryWrapper<Article>().select("id", "create_date", "create_by", "title", "summary", "image", "article_type", "views","quote_link", "is_top", "commentSize").eq("is_top", "1").eq("article_type", typeId).orderByDesc("create_date"));
			ArrayList<Article> articleList2 = new ArrayList<>(list3);


			// 再存入剩余文章
			List<Article> list4 = iArticleService.list(new QueryWrapper<Article>().select("id", "create_date", "create_by", "title", "summary", "image", "article_type", "views","quote_link", "commentSize").eq("is_top", "0").eq("article_type", typeId).orderByDesc("create_date"));
			articleList2.addAll(list4);
			model.addAttribute("articleList", articleList2);
			return "article::articleList";
		}
	}


	/**
	 * @return 搜索框的结果
	 */
	@PostMapping("/searchResult")
	public String getSearchResult(String text, Model model,HttpServletRequest request) {
		List<Article> articles = iArticleService.list(new QueryWrapper<Article>().like("title", text).select("id", "create_date", "create_by", "title", "summary", "image", "article_type", "views", "quote_link","commentSize"));
		model.addAttribute("articleList", articles);

		//将类型信息封装存进request域中
		List<Type> categoryNavigation = iTypeService.list();
		request.setAttribute("categoryNavigation", categoryNavigation);

		log.info("接收的搜索参数：{}", text);
		for (Article article :
				articles) {
			log.info("搜索匹配的文章标题：{}", article.getTitle());
		}
		return "article::articleList";
	}

	/**
	 * @return 留言页面
	 */
	@GetMapping("/message")
	public String message(HttpSession session) {
		List<Comment> comments = iCommentService.listComment(0);
		session.setAttribute("originList", comments);
		return "message";
	}


	/**
	 * 1、用户在index点击“阅读更多”或者头图片链接、在article页点击标题或者“继续阅读”
	 * 2、点击后获取文章Id在数据库查询并封装文章信息，封装该类型阅读量最多的两个文章信息并封装
	 * 3、在read页面展示
	 * @return 文章详情页
	 */
	@GetMapping("/read/{articleId}/{articleType}")
	public String read(@PathVariable("articleId") int articleId, @PathVariable("articleType") int articleType, HttpServletRequest request, HttpSession session) {

		/*
		  进行浏览次数的累加逻辑
		  将ip信息作为一个键值存入redis中，浏览时，查找redis中有没有该键值，没有，就加入缓存，设定三个小时的过期时间，将浏览次数加1，有就不计算
		  暂时简单实现
		 */

		Article article = iArticleService.getById(articleId);
		//2、对信息进行封装
		request.setAttribute("article", article);
		log.info("跳转到read页");
		article.setViews(article.getViews()+1);
		iArticleService.updateById(article);
		//3.通过页面传过来的文章类型参数查找该类型阅读量最多的两个文章信息并封装
		List<Article> mostPopularArticlesByTypes = iArticleService.getMostPopularArticlesByType(articleType);
		request.setAttribute("mostPopularArticlesByTypes", mostPopularArticlesByTypes);

		List<Comment> comments = iCommentService.listComment(articleId);
		session.setAttribute("originList", comments);
		return "read";
	}


	/**
	 * @return 日记页
	 */
	@GetMapping("/diary")
	public String diary(Model model) {
		//找出所有日记，按照年份分好组
		ArrayList<List<Diary>> diaryList = iDiaryService.getDiaryList();
		model.addAttribute("diaryList", diaryList);
		return "diary";
	}
}


